import Vue from 'vue';
import { apiGet, apiPost } from "@/api/api-common.js";
import Layout from '@/page/index/'
import { getStore } from "./store";
import { getToken } from "@/util/auth";

function install(Vue) {

    Vue.mixin({
        methods: {
            _qbSetVal(key, val) { //用于qb的独特设置值的方法,将数值返回到父组件。 注意 key中暂时不支持[],只支持.分隔
                let prekey = "";
                let lastkey = key;
                if (key.lastIndexOf(".") > -1) {
                    prekey = key.substring(0, key.lastIndexOf("."));
                    lastkey = key.substring(key.lastIndexOf(".") + 1);
                }
                if (prekey) {
                    eval("Vue.set(this._that." + prekey + ",lastkey,val)");
                } else {
                    Vue.set(this._that, lastkey, val)
                }
            },


            /**
             *
             * @param title
             * @param url  必须是views下的页面，例  /integrate/components/choose_new_meeting.vue  是指 src/views/integrate/components/choose_new_meeting.vue
             * @param options
             * @param backfunc
             * @returns {*}
             */
            $dwin(url, title, options, backfunc) { //特殊的弹窗，不用引入组件，组件写在index.vue
                if (url.indexOf("@/views") > -1) {
                    url = url.substring(7, url.length);
                }

                let holdwintop = null; //根据是否存在名为holdwin的组件，来向上查找 src/page/index/index.vue 页面
                let outtop = this;
                while (outtop.$parent) {
                    if (outtop.$parent.holdwinFlag) {
                        holdwintop = outtop.$parent;
                        break;
                    } else {
                        outtop = outtop.$parent;
                    }
                }
                if (holdwintop) {
                    if (holdwintop.holdwinShowFlag) { //如果第一弹窗已经打开，就开第二个
                        holdwintop.holdwinTitle2 = title;
                        holdwintop.holdwinUrl2 = url;
                        if (options && options.width) {
                            holdwintop.holdwinWidth2 = options.width;
                        }
                        return holdwintop.$win("holdwin2", options, backfunc)
                    } else {
                        holdwintop.holdwinTitle = title;
                        holdwintop.holdwinUrl = url;
                        holdwintop.holdwinShowFlag = true;
                        if (options && options.width) {
                            holdwintop.holdwinWidth = options.width;
                        }
                        return holdwintop.$win("holdwin", options, backfunc)
                    }
                }
            },


            $win(ref, options, bacfunc) { //打开一个组件
                let _ref = this.$refs[ref];
                if (!_ref) {
                    alert("未查询到ref[" + ref + "]的组件！");
                    return;
                }
                return new Promise((outresolve, outreject) => {
                    _ref.outresolve = outresolve;
                    if (bacfunc) {
                        _ref._bacfunc = bacfunc;
                    }
                    if (!_ref.$open) {
                        alert("请在子组件中编写$open函数，否则父组件不应该使用$win调用");
                        return;
                    }
                    options = options || {};
                    _ref.$open(options);
                });
            },

            $close(backdata) { //子组件传回数据,并不会有关闭动作，只是通常用于关闭时传值。注意只能传一个值，所以，有时需要数组或对象
                if (this.outresolve) {
                    //关闭动作
                    this.outresolve(backdata);
                }
                if (this._bacfunc) {
                    this._bacfunc(backdata);
                }
            },

            $back(backdata) { //只通过回调函数传值，不会触发promise
                if (this._bacfunc) {
                    this._bacfunc(backdata);
                }
            },


            $getRules() { //根据页面打印验证
                let allstr = 'rules:{\r\n';
                document.querySelectorAll(".el-form-item__label").forEach((item) => {
                    let foritem = item.getAttribute("for");
                    let forname = item.innerHTML;
                    if (forname != null && forname.endsWith("：")) {
                        forname = forname.substring(0, forname.length - 1);
                    }

                    // {pattern: /^(([1-9][0-9]*(\.[0-9]{1,2})?)|([0]\.[0-9]{1,2}))$/, message: '最多两位小数', trigger: 'blur'}

                    let itemstr = `${foritem}: [{ required: true, message: "请输入${forname}", trigger: "click" },],\r\n`;
                    allstr += itemstr;
                })
                allstr += "}\r\n";
                console.log("=======生成验证\r\n", allstr)
            },


            $vd(parentNode) { //验证方法，结合 v-vd="r" 使用  parentNode是document对象
                let wfunc = (vflag, el, dmsg, rulemsg) => { //提示警告
                    if (dmsg == null || dmsg == "") {
                        dmsg = rulemsg;
                    }

                    let tmpinput = el.querySelector("input,textarea");
                    let tmpstyle = tmpinput.style.border;
                    let errtipnode = document.createElement("span");
                    errtipnode.innerText = dmsg;
                    errtipnode.style = "color:red;position: absolute;right: 20px;top: 15px;font-size:10px";
                    el.parentNode.appendChild(errtipnode);
                    tmpinput.style.border = "1px solid red";
                    setTimeout(() => {
                            tmpinput.style.border = tmpstyle;
                            el.parentNode.removeChild(errtipnode);
                        }, 5000)
                        // if(vflag){//只有第一条消息会提示
                        //   this.$message.warning(dmsg);
                        // }
                }

                let firstvmsg = true;
                let pobj = document;
                if (parentNode) {
                    pobj = parentNode;
                }
                let allitems = pobj.querySelectorAll("[vd]");
                if (allitems != null && allitems.length > 0) {
                    for (let i = 0; i < allitems.length; i++) {
                        let item = allitems[i];
                        if (item.getAttribute("vd")) {
                            let tmpvd = item.getAttribute("vd");
                            if (tmpvd == null || tmpvd == "") continue; //空验证跳过
                            let tmpvdname = item.getAttribute("vdn");
                            let tmpvalue = eval("this." + tmpvdname);
                            let pies = tmpvd.split(",");
                            if (pies && pies.length > 0) {
                                for (let j = 0; j < pies.length; j++) {
                                    let uitem = pies[j];
                                    let rule = uitem.trim();
                                    let vmsg = null;
                                    if (uitem.indexOf("|") > 0) {
                                        let vpies = uitem.split("|");
                                        rule = vpies[0];
                                        vmsg = vpies[1].replace(new RegExp("['\"]", "g"), "");
                                    }
                                    /**
                                     * 核验证部分
                                     */
                                    if (rule == 'r' || rule == 'R') { //必填验证
                                        if (tmpvalue == null || tmpvalue == "" || tmpvalue.length == 0) {
                                            wfunc(firstvmsg, item, vmsg, "不能为空");
                                            firstvmsg = false;
                                        }
                                    } else if (rule.startsWith("max")) { //必填验证
                                        console.log("最大");
                                    } else if (rule.startsWith("min")) { //必填验证
                                        console.log("最小");
                                    } else if (rule == "phone") { //手机验证
                                        if(tmpvalue){
                                          if(!/^1[0-9]{10}$/.test(tmpvalue)){
                                            wfunc(firstvmsg, item, vmsg, "必须为11位手机格式");
                                            firstvmsg = false;
                                          }
                                        }
                                    } else if (rule == "eid") { //必填验证
                                        console.log("身份证");
                                    } else {
                                        console.log("无效验证:" + tmpvd, tmpvdname)
                                    }
                                }
                            }
                        }
                    }
                }
                return firstvmsg; //当有一条错误，就返回false

            },

            /**
             * 例： this.$go2page("是否设置公开","@/views/integrate/baseproject/library/guquan_edit_setting_public.vue",{id:row.id});
             */
            $go2page(name, page, pams) {
                let tmpurl = page;
                if (tmpurl.indexOf("/plugin/") > -1) {
                    tmpurl = tmpurl.replace("/plugin/", "/");
                }
                if (tmpurl.endsWith(".vue")) {
                    tmpurl = tmpurl.substring(0, tmpurl.length - 4);
                }
                let patharr = tmpurl.split("/");

                let firstpath = '/' + patharr[2];
                patharr.splice(0, 3);
                let restpath = patharr.join("/");

                this.$router.addRoutes([{
                    path: firstpath,
                    component: Layout,
                    children: [{
                        path: restpath,
                        name: name,
                        component: () =>
                            import (`@/views${firstpath+"/"+restpath+".vue"}`),
                    }]
                }])

                let tmplist = [];
                let tmplisttr = window.sessionStorage.getItem("go2pagedrouter");
                if (tmplisttr && tmplisttr.length > 1) {
                    tmplist = JSON.parse(tmplisttr);
                }

                let hasflag = false;
                for (let i = 0; i < tmplist.length; i++) {
                    if (tmplist[i].name == name && tmplist[i].page == page) {
                        hasflag = true;
                        break;
                    }
                }
                if (!hasflag) {
                    tmplist.push({ name: name, page: page });
                }
                window.sessionStorage.setItem("go2pagedrouter", JSON.stringify(tmplist));

                if (pams == null) {
                    pams = {};
                }
                pams['tagtitle'] = encodeURIComponent(name);
                this.$router.push({ path: firstpath + "/" + restpath, query: pams });
            },

            $go2Process(sn) {
                apiGet("/blade-workflow/process/getWfProcessBySn", { sn }).then((res) => {
                    if (res.data.data) {
                        this.$dynamicRoute(res.data.data, "detail");
                    }
                })
            },
            $go2ProcessById(id, proKey) {
                apiGet("/blade-workflow/process/$go2ProcessById", { id, proKey }).then((res) => {
                    if (res.data.data) {
                        this.$dynamicRoute(res.data.data, "detail");
                    }
                })
            },

            $terminateProcessByID(id, proKey, bizTable, backfunc) {
                this.$confirm("是否确定撤回流程?", {
                    confirmButtonText: "确定",
                    cancelButtonText: "取消",
                    type: "warning",
                }).then(res => {
                    apiGet("/blade-workflow/process/$terminateProcessByID", { id, proKey, bizTable }).then((res) => {
                        if (backfunc) {
                            bakfunc(res);
                        } else {
                            this.$message.success('撤回成功')
                            this.searchReset();
                        }
                    })
                })
            },

            $dynamicRoute(row, type) {
                console.log(row);
                console.log(type);
                const { id, taskId, processInstanceId, processId, formKey, formUrl } = row
                let param = Buffer.from(JSON.stringify({
                    processId: id,
                    taskId,
                    processInsId: processInstanceId || processId
                })).toString('base64')

                if (formKey && formKey.startsWith('wf_ex_')) {
                    if (formUrl) { // 配置了自定义路由
                        this.$router.push(formUrl + `?p=${param}`)
                    } else { // 动态添加路由
                        this.$router.addRoutes([{
                            path: `/workflow/process/external`,
                            component: Layout,
                            children: [{
                                path: `${formKey.substring(6)}/${type}`,
                                name: type == 'start' ? '发起流程' : '流程详情',
                                component: () =>
                                    import ( /* webpackChunkName: "views" */ `@/views/plugin/workflow/process/external/${formKey.substring(6)}/${type}.vue`),
                            }]
                        }])
                        this.$router.push(`/workflow/process/external/${formKey.substring(6)}/${type}?p=${param}`)
                    }
                } else {
                    this.$router.push(`/workflow/process/${type}/${param}`)
                }
            },

            $extendFileds(table) { //获取扩展字段配置，并覆盖form中的extendFileds字段，只用于新增时，修改时，是后台通过Wrapper实现的。
                return apiPost("wtools/cdinter/extendfileconfig/init", { table: table }).then((res) => {
                    this.$set(this.form, "extendFileds", res.data.data)
                });
            },
            //举例 formatter:row=>this.$fmtLink("#/stockright/latentproject/latent_view?id="+row.id,row.name)
            $fmtLink(link, name) {
                return `<a href="${link}" class="handle_color">${name}</a>`;
            },

            // //举例 formatter:row=>this.$fmtIndustry(row,row.industryid,'inddustryName')
            // $fmtIndustry(row,val,backname){
            //   if(!val)return "";
            //   if(typeof val === 'string'){
            //     apiPost("wtools/cdinter/industry/getnames", {ids: val}).then((res)=>{
            //        this.$set(row,backname,res.data.data);
            //     });
            //     return row[backname];
            //   }
            //   return ""
            // }



            /**
             * 模板导出
             * @param tpl 模板路径 例 excel/gclstat.xlsx
             * @param title 下载文件名称，不要后缀
             * @param jsonmp 模板需要参数
             */
            $easy2excel(tpl, title, jsonmp) {
                let pams = { tpl: tpl, title: title, body: JSON.stringify(jsonmp) };
                let url = `/api/wtools/cdinter/common/easypoi-export-xml?${this.website.tokenHeader}=${getToken()}`;
                this.$submitForm(url, pams);
            },


          /**
           * 批量下载
           * @param list  列表
           * @param filed  文件对应的字段值
           * @param name  打包文件名称
           */
            $batchDown(list,filed,name){
              let alllist = [];
              for (let i = 0; i <list.length ; i++) {
                let row = list[i];
                if(row[filed]){
                   let tmpflist = eval("(" +row[filed] + ")") ;
                   if(tmpflist&&tmpflist.length>0){
                     alllist.push(...tmpflist);
                   }
                }
              }
              this.zipdown(name?name:'打包',alllist);
            },




          /**
           *
           * 使用avue的 column 来生成表格，支持复杂表头  调用：例如  this.$excelAvue("测试",this.data,this.option.column);
           * @param title
           * @param list
           * @param head label是名称，prop对应list中数据，align是靠左或居中(默认居中), 扩展三个可选属性：宽度，头部字体，内容字体  excelWidth:20,excelHeadFont:18,excelFont:14,
           * @config {sheetName:'',headHeight:24,bodyHeight:14,rowHeight:{row1:14,row3:24} }  注：sheetName是sheet的名称，headHeight是所有头部行高  bodyHeight 是所有数据行的行高 ,rowHeight是特定行的行高
           */


          _downdeleteHide(hlist){
            if(hlist!=null&&hlist.length>0){
              for (let i = 0; i < hlist.length; i++) {
                if(hlist[i].hide==true){//如果隐藏，则删除
                  hlist.splice(i,1);
                  i--;
                }else{
                  if(hlist[i].children&&hlist[i].children.length>0){
                    this._downdeleteHide(hlist[i].children);
                  }
                }
              }
            }
          },

          _downdeleteHideOther(hlist,showColumn){
            if(hlist!=null&&hlist.length>0){
              for (let i = 0; i < hlist.length; i++) {
                if(hlist[i].prop){
                  if(showColumn.indexOf(hlist[i].prop)<0){
                    hlist.splice(i,1);
                    i--;
                    continue;
                  }
                }
                if(hlist[i].children&&hlist[i].children.length>0){
                  this._downdeleteHideOther(hlist[i].children,showColumn);
                }
              }
            }
          },


          /**
           *
           * 通常如下使用，如果要动态控制显隐列，则需要 需要avue上配置  :show-column.sync="showColumn"，data中定义showColumn,  config中增加  showColumn:this.showColumn,
           *
           getList(1, -1, this.query).then((res) => {
            this.$excelAvue(
              "项目入驻通知单",
              res.data.data.records,
              this.option.column,
              {
                headHeight: 30,
                bodyHeight: 30,
                index: true,
              }
            );
           });

           head常用配置说明
           excelHeadFont：标题字体大小，数字型
           excelFont:  主体内容字体大小，数字型
           excelWidth:  列宽度，数字型
           hide: 隐藏列
           align: 内容居左或居中，默认居中(这点与页面居左不太一致，主要是excel居左不太好看，如果有必要居左，请直接指定)
           有必要可以扩展颜色之类的，但现在感觉还没必要

           *config常用说明
           * headHeight 标题行的高度
           * bodyHeight 数据行的高度 包括footer
           * index 是否显示序号列
           * sheetName  sheet页名称
           * rowHeight  json对象，例 {row3:35,row7,10} 指定具体某行的高度
           * topTitle  增加顶部行，写一个标题
           * footer   底部合计等，列：可以写列合并，颜色，字体大小 ，注意颜色目前只支持  red,blue,yellow,更多需要修改后台接口
           *    let footer = [
           [{value:'总计',colspan:2},163,99],
           [{value:'所有',colspan:5,excelFont:16,color:"blue",border:false},{value:'899',color:"red"}],
           ]

           *
           */
          $excelAvue(title,list,head,config){
            let pams = {title:title};

            let posthead = JSON.parse(JSON.stringify(head));//除掉其中hide属性的列
            if(posthead!=null&&posthead.length>0){
              this._downdeleteHide(posthead);//把hide属性为true的隐藏
            }

            if(config!=null){
              //按showColumn显示，隐藏其它不必要列，通常用于动态显隐列，需要avue上配置  :show-column.sync="showColumn"，data中定义showColumn,config中增加  showColumn:this.showColumn,
              if(config.showColumn&&config.showColumn.length>0){
                this._downdeleteHideOther(posthead,config.showColumn);
              }

              if(config.index==true){
                posthead.unshift({
                  label:'序号',
                  prop:'_innerind',
                  excelWidth:5,
                });
                if(list&&list.length>0){
                  for (let i = 0; i < list.length; i++) {
                    list[i]._innerind=i+1;
                  }
                }
              }
              if(config.topTitle){
                let newposthead = [{
                  label:config.topTitle,
                  children:posthead
                }]
                posthead = newposthead;
              }
            }

            if (list) { pams.list = JSON.stringify(list);}
            if (head) { pams.head = JSON.stringify(posthead);}
            if (config) { pams.config = JSON.stringify(config);}
            let url = `/api/wtools/cdinter/common/avueExcel?${this.website.tokenHeader}=${getToken()}`;
            this.$submitForm(url,pams);
          },


            $submitForm(url, pams) {
                let generateHideElement = function(name, value) {
                    let tempInput = document.createElement("input");
                    tempInput.type = "hidden";
                    tempInput.name = name;
                    tempInput.value = value;
                    return tempInput;
                }

                let form = document.createElement("form");
                for (let key in pams) {
                    form.appendChild(generateHideElement(key, pams[key]));
                }
                document.body.appendChild(form);
                form.method = "post";
                form.target = "_blank";
                form.action = url;
                form.submit();
                document.body.removeChild(form);
            },
        }
    })

}

if (window.Vue) {
    install(window.Vue);
} else {
    install(Vue);
}

export default install;
